// 发布 - 订阅模式是一种设计模式。
// 它定义了一种一对多的依赖关系，让多个观察者对象同时监听一个主题对象。
// 这个主题对象在状态发生变化时，会通知所有观察者对象，使它们能够自动更新自己的状态。


class EventEmitter {
  constructor() {
    // 用于存储事件和对应的回调函数列表
    this.events = {};
  }

  // 订阅事件的方法
  on(eventName, callback) {
    if (!this.events[eventName]) {
      // 如果该事件还没有对应的回调函数列表，创建一个空数组
      this.events[eventName] = [];
    }
    // 将回调函数添加到该事件的回调函数列表中
    this.events[eventName].push(callback);
  }

  // 发布事件的方法
  emit(eventName, ...args) {
    if (this.events[eventName]) {
      // 遍历该事件的回调函数列表
      this.events[eventName].forEach(callback => {
        // 依次调用每个回调函数，并传入参数
        callback(...args);
      });
    }
  }

  // 取消订阅事件的方法
  off(eventName, callback) {
    if (this.events[eventName]) {
      // 过滤掉指定的回调函数
      this.events[eventName] = this.events[eventName].filter(cb => cb !== callback);
    }
  }
}

// 使用示例
const emitter = new EventEmitter();

// 定义一个回调函数
const callback = (message) => {
  console.log(`Received message: ${message}`);
};

// 订阅事件
emitter.on('message', callback);

// 发布事件
emitter.emit('message', 'Hello, World!');

// 取消订阅
emitter.off('message', callback);

// 再次发布事件，此时回调函数不会被调用
emitter.emit('message', 'This message won\'t be received.');    